package com.bosicloud.cmb.ibp.microplatform.controller;

import com.bosicloud.cmb.ibp.microplatform.commom.constant.UrlDefine;
import com.bosicloud.cmb.ibp.microplatform.commom.model.*;
import com.bosicloud.cmb.ibp.microplatform.commom.vo.*;
import com.bosicloud.cmb.ibp.microplatform.service.MicroPlatformManagerService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

import static com.bosicloud.cmb.ibp.microplatform.commom.constant.CloudFormationConstant.COMPLETE_STATUS;


@Slf4j
@RestController
@Api(value = "自动化微服务平台控制器", description = "自动化微服务平台")
public class MicroPlatformManagerController {

    @Autowired
    MicroPlatformManagerService MicroPlatformManagerService;

    @ApiOperation(value = "创建微服务平台", response = String.class)
    @HystrixCommand
    @PostMapping(value = UrlDefine.CREATE_MICRO_SERVICE_PLATFORM)
    public String createMicroServicePlatform(@RequestBody @Valid CreateMicroPlatformVO platformVO) {
        return MicroPlatformManagerService.createMicroServicePlatform(platformVO);
    }


    @ApiOperation(value = "查询微服务环境列表", response = EnvListVO.class)
    @HystrixCommand
    @GetMapping(value = UrlDefine.SEARCH_ENV_LIST + "/{userId}",
            produces = MediaType.APPLICATION_JSON_VALUE)
    public List<EnvListVO> searchEnvList(@ApiParam(name = "userId", value = "用户ID", required = true)
                                         @PathVariable(value = "userId") Integer userId) {
        return MicroPlatformManagerService.searchEnvList(userId);
    }

    @ApiOperation(value = "根据平台环境ID查询平台组件列表", response = IbpPlatformInfo.class)
    @HystrixCommand
    @GetMapping(value = UrlDefine.SEARCH_PLATFORM_COMPONENT_LIST + "/{environmentId}/{envName}",
            produces = MediaType.APPLICATION_JSON_VALUE)
    public IbpPlatformInfo searchPlatformComponentList(@ApiParam(name = "environmentId", value = "平台环境ID", required = true)
                                                       @PathVariable(value = "environmentId") Integer environmentId,
                                                       @ApiParam(name = "envName", value = "环境", required = true)
                                                       @PathVariable(value = "envName") String envName) {
        return MicroPlatformManagerService.searchPlatformInfoByEnvironmentId(environmentId, envName);
    }

    @ApiOperation(value = "根据Token查询事件日志", response = IbpCfNotifyMessage.class)
    @HystrixCommand
    @GetMapping(value = UrlDefine.SEARCH_CF_NOTIFY_MESSAGE + "/{token}",
            produces = MediaType.APPLICATION_JSON_VALUE)
    public List<IbpCfNotifyMessage> searchCfNotifyMessage(@ApiParam(name = "token", value = "创建微服务平台时的token", required = true)
                                                          @PathVariable(value = "token") String token) {
        return MicroPlatformManagerService.searchCfNotifyMessage(token);
    }

    @ApiOperation(value = "根据平台环境/envName查询集群名称是否存在", response = Boolean.class)
    @HystrixCommand
    @GetMapping(value = UrlDefine.CHECK_CLUSTERNAME_ISEXITS + "/{envName}/{clusterName}")
    public Boolean checkClusterNameIsExits(@ApiParam(name = "envName", value = "平台环境", required = true)
                                           @PathVariable(value = "envName") String envName,
                                           @ApiParam(name = "clusterName", value = "集群名称", required = true)
                                           @PathVariable(value = "clusterName") String clusterName) {

        return Optional.ofNullable(MicroPlatformManagerService.searchMspEnvironment(envName, clusterName))
                .isPresent();
    }


    @ApiOperation(value = "根据token查询微服务平台环境信息", response = IbpMspEnvironment.class)
    @HystrixCommand
    @GetMapping(value = UrlDefine.SEARCH_MSPENVIRONMENT + "/{token}")
    public IbpMspEnvironment searchMspEnvironmentByToken(@ApiParam(name = "token", value = "token", required = true)
                                                         @PathVariable(value = "token") String token) {
        return MicroPlatformManagerService.searchMspEnvironmentByToken(token);

    }

    @ApiOperation(value = "部署微服务", response = String.class)
    @HystrixCommand
    @PostMapping(value = UrlDefine.DEPLOY_SERVICE)
    public String deployService(@RequestBody @Valid DeployServiceVO deployServiceVO) {
        return MicroPlatformManagerService.deployService(deployServiceVO);
    }

    @ApiOperation(value = "根据微服务环境查询集群名称列表", response = String.class)
    @HystrixCommand
    @GetMapping(value = UrlDefine.SEARCH_CLUSTER_NAME_LIST + "/{userId}/{envName}",
            produces = MediaType.APPLICATION_JSON_VALUE)
    public List<String> searchClusterNameList(@ApiParam(name = "userId", value = "用户ID", required = true)
                                              @PathVariable(value = "userId") Integer userId,
                                              @ApiParam(name = "envName", value = "环境名称", required = true)
                                              @PathVariable(value = "envName") String envName) {
        Map<String, List<EnvListVO>> collect = MicroPlatformManagerService.searchEnvList(userId)
                .stream()
                .collect(Collectors.groupingBy(EnvListVO::getEnvName));
        return Optional.ofNullable(collect)
                .filter(MapUtils::isNotEmpty)
                .map(rs -> rs.get(envName))
                .orElse(Collections.emptyList())
                .stream()
                .filter(Objects::nonNull)
                .filter(rs -> Objects.equals(COMPLETE_STATUS, rs.getStatus()))
                .map(EnvListVO::getClusterName)
                .collect(Collectors.toList());
    }


    @ApiOperation(value = "查询微服务列表", response = ServiceListVO.class)
    @HystrixCommand
    @GetMapping(value = UrlDefine.SEARCH_SERVICE_LIST + "/{environmentId}",
            produces = MediaType.APPLICATION_JSON_VALUE)
    public List<ServiceListVO> searchServiceList(@ApiParam(name = "environmentId", value = "环境ID", required = true)
                                                 @PathVariable(value = "environmentId") Integer environmentId) {

        return MicroPlatformManagerService.searchMspDeployListByEnvironmentId(environmentId)
                .stream()
                .map(rs -> {
                    ServiceListVO serviceListVO = new ServiceListVO();
                    BeanUtils.copyProperties(rs, serviceListVO);
                    serviceListVO.setAwsTaskName(rs.getServiceName());
                    return serviceListVO;
                })
                .collect(Collectors.toList());

    }

    @ApiOperation(value = "根据环境,集群名,服务类型查询部署服务信息", response = IbpMspDeploy.class)
    @HystrixCommand
    @GetMapping(value = UrlDefine.SEARCH_DEPLOY_SERVICE_INFO + "/{envName}/{clusterName}/{serviceType}/{serviceName}",
            produces = MediaType.APPLICATION_JSON_VALUE)
    public IbpMspDeploy searchDeployServiceInfo(@ApiParam(name = "envName", value = "环境名称", required = true)
                                                @PathVariable(value = "envName") String envName,
                                                @ApiParam(name = "clusterName", value = "集群名称", required = true)
                                                @PathVariable(value = "clusterName") String clusterName,
                                                @ApiParam(name = "serviceType", value = "服务类型", required = true)
                                                @PathVariable(value = "serviceType") String serviceType,
                                                @ApiParam(name = "serviceName", value = "服务名称", required = true)
                                                @PathVariable(value = "serviceName") String serviceName) {

        return MicroPlatformManagerService.searchMspDeploy(IbpMspDeploy
                .builder()
                .envName(envName)
                .clusterName(clusterName)
                .serviceName(serviceName)
                .build());

    }

    @ApiOperation(value = "根据部署ID,任务名称查询部署错误信息", response = IbpApiAwsFailtMsg.class)
    @HystrixCommand
    @GetMapping(value = UrlDefine.SEARCH_FAIL_MESSAGE + "/{deployId}/{taskName}",
            produces = MediaType.APPLICATION_JSON_VALUE)
    public IbpApiAwsFailtMsg searchFailMessage(@ApiParam(name = "deployId", value = "部署ID", required = true)
                                               @PathVariable(value = "deployId") Integer deployId,
                                               @ApiParam(name = "taskName", value = "任务名称", required = true)
                                               @PathVariable(value = "taskName") String taskName) {

        return MicroPlatformManagerService.searchFailMsg(deployId, taskName);

    }


    @ApiOperation(value = "根据环境和集群名查询微服务环境信息", response = IbpMspEnvironment.class)
    @HystrixCommand
    @GetMapping(value = UrlDefine.SEARCH_MSPENVIRONMENT_INFO + "/{envName}/{clusterName}")
    public IbpMspEnvironment searchMspEnvironmentInfo(@ApiParam(name = "envName", value = "envName", required = true)
                                                      @PathVariable(value = "envName") String envName,
                                                      @ApiParam(name = "clusterName", value = "clusterName", required = true)
                                                      @PathVariable(value = "clusterName") String clusterName) {
        return MicroPlatformManagerService.searchMspEnvironment(envName, clusterName);

    }

    @ApiOperation(value = "添加项目信息", response = String.class)
    @HystrixCommand
    @PostMapping(value = UrlDefine.ADD_PROJECT_INFO)
    public String saveProjectInfo(@RequestBody @Valid ProjectInfoVO projectInfoVO) {
        return MicroPlatformManagerService.saveProjectInfo(projectInfoVO);
    }

    @ApiOperation(value = "查询当前用户项目信息", response = IbpMspProjectInfo.class)
    @HystrixCommand
    @GetMapping(value = UrlDefine.SEARCH_PROJECT_INFO + "/{userId}")
    public IbpMspProjectInfo searchProjectInfo(@ApiParam(name = "userId", value = "登录用户ID", required = true)
                                               @PathVariable(value = "userId") Integer userId) {
        return MicroPlatformManagerService.searchProjectInfo(IbpMspProjectInfo
                .builder()
                .createUser(userId)
                .build())
                .orElse(null);
    }


}
